package com.boco.service.impl;

import com.boco.anno.HisConverter;
import com.boco.common.converter.ObjectConverter;
import com.boco.service.IConvertService;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author pandengke/pdkkpdk@163.com
 * @date 2018/11/14
 */
@Service
public class ConvertServiceImpl implements IConvertService {

    Map<HisConverter, ObjectConverter> map = new ConcurrentHashMap<>();

    @Override
    @Cacheable("hisConverters")
    public ObjectConverter newInstance(HisConverter hisConverter) {
        if (map.containsKey(hisConverter)) {
            return map.get(hisConverter);
        }
        ObjectConverter converter;
        assert hisConverter != null;
        try {
            converter = hisConverter.value().newInstance();
            converter.setClazz(hisConverter.toClazz());
            map.put(hisConverter,converter);
            return converter;
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public List convert(List from, ObjectConverter converter) {
        assert from != null;
        /*如果列表为空,直接返回空列表*/
        if (from.isEmpty()) {
            return new ArrayList<>();
        }
        if (converter == null) {
            HisConverter hisConverter = from.get(0).getClass().getAnnotation(HisConverter.class);
            assert hisConverter != null;
            converter = newInstance(hisConverter);
        }
        assert converter != null;
        return (List) from.stream().map(converter::convert).collect(Collectors.toList());
    }

    @Override
    public List convert(List from) {
        return convert(from, null);
    }

    @Override
    public Object convert(Object from) {
        ObjectConverter converter;
        HisConverter hisConverter = from.getClass().getAnnotation(HisConverter.class);
        converter = newInstance(hisConverter);
        if (converter != null) {
            return converter.convert(from);
        }
        return null;
    }
}
